﻿using System;
using System.Text;

namespace CommLib
{
    public enum SmsStatus 
    {
		Received, Delivered, Sent, Sending, Unknown
	}

	public enum SmsType 
    {
		Received, Sent, Draft, Unknown
	}

    public class Sms
    {
        public readonly static int FIELD_COUNT = 6;

	    private readonly String mText;
	    private readonly DateTime mDate;
	    private readonly SmsType mType;
	    private readonly int mThreadId;
	    private readonly String mNumber;
	    private readonly SmsStatus mStatus;

        public Sms(String text, DateTime date, SmsType type, int threadId,
			    String number, SmsStatus status)
        {
		    mText = text;
		    mDate = date;
		    mType = type;
		    mThreadId = threadId;
		    mNumber = number;
		    mStatus = status;
	    }

        public Sms(String text, DateTime date, int type, int threadId, String number,
			    int status)
		    : this(text, date, getSmsType(type), threadId, number,
				    getSmsStatus(status))
        {
	    }

	    public Sms(String[] data, int firstIdx) 
        {
		    if (data.Length - firstIdx < FIELD_COUNT)
			    throw new ArgumentException("Too few data fields!");

		    mText = data[firstIdx++];
            // Eingehendes Datum beginnt am 01.01.1970, ist in Millisekunden
            // DateTime zählt aber ab 0001
		    mDate = BluetoothMessage.parseDateTime(long.Parse(data[firstIdx++]));
		    mType = (SmsType)int.Parse(data[firstIdx++]);
		    mThreadId = int.Parse(data[firstIdx++]);
		    mNumber = data[firstIdx++];
		    mStatus = (SmsStatus)int.Parse(data[firstIdx++]);
	    }

	    public String getText() 
        {
		    return mText;
	    }

	    public DateTime getDate() 
        {
		    return mDate;
	    }

	    public SmsType getType() 
        {
		    return mType;
	    }

	    public int getThreadId() 
        {
		    return mThreadId;
	    }

	    public String getNumber() 
        {
		    return mNumber;
	    }

	    public SmsStatus getStatus() 
        {
		    return mStatus;
	    }

	    public String getDateString() 
        {
		    StringBuilder b = new StringBuilder();
		    b.Append(smsTypeToString(mType));
		    b.Append(": ");
            b.Append(mDate.ToString());

		    if (!mStatus.Equals(SmsStatus.Received)) {
			    b.Append(" - Status: ");
			    b.Append(smsStatusToString(mStatus));
		    }

		    return b.ToString();
	    }

	    public override string ToString() {
		    return getDateString() + "\r\n" + mText;
	    }

        private static SmsType getSmsType(int androidType)
        {
            switch (androidType) 
            {
			case 1:
				return SmsType.Received;

			case 2:
				return SmsType.Sent;

			case 3:
				return SmsType.Draft;

			default:
				return SmsType.Unknown;
			}
        }

        private static SmsStatus getSmsStatus(int androidStatus)
        {
            switch (androidStatus) 
            {
			case -1:
				return SmsStatus.Received;

			case 0:
				return SmsStatus.Delivered;

			case 34:
				return SmsStatus.Sent;

			default:
				return SmsStatus.Unknown;
			}
        }

        private static string smsStatusToString(SmsStatus status)
        {
            switch (status)
            {
            case SmsStatus.Received:
                return "Empfangen";

            case SmsStatus.Sent:
                return "Nicht zugestellt";

            case SmsStatus.Delivered:
                return "Zugestellt";
            
            case SmsStatus.Sending:
                return "Wird gesendet";

            default:
                return "Unbekannt";
            }
        }

        private static string smsTypeToString(SmsType type)
        {
            switch (type)
            {
            case SmsType.Received:
                return "Empfangen";
            case SmsType.Sent:
                return "Gesendet";
            case SmsType.Draft:
                return "Entwurf";
            default:
                return "Unbekannt";
            }
        }

    }
}
